package com.lt.test.consumer.web.controller;

import com.lt.test.api.UserService;
import com.lt.test.common.constant.HttpRequestConstant;
import com.lt.test.common.constant.ShiroMd5HashConstant;
import com.lt.test.common.exception.CustomException;
import com.lt.test.common.util.SMSUtil;
import com.lt.test.common.util.StringUtils;
import com.lt.test.entity.DO.UserDO;
import com.lt.test.entity.DTO.*;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;


/**
 * 用户相关控制器
 * @author zhengchuan
 *
 */
@Controller
@RequestMapping("/sys/user")
public class UserController {
	private static final Logger logger = LoggerFactory.getLogger(UserController.class);
	@Autowired
	private UserService userService;

	/**
	 * 首页跳转接口
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/index")
	public String index() {
		return "content/index";
	}

	/**
	 * 登陆和授权接口
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/home")
	public String home(HttpServletRequest request, HttpServletResponse response, Model model) {
	/*	Object obj = request.getSession().getAttribute(SessionConstant.SESSION_USER_INFO);
		if (obj != null) {
			UserDO sesssionUser = (UserDO) obj;
			try {
				List<MenuDTO> menus = userService.findUserMenusByRoleId(sesssionUser.getRoleId());
				request.setAttribute("menus", menus);
				return "index";
			} catch (CustomException e) {
				e.printStackTrace();
			} catch (Exception e) {
				return "login";
			}
		}
		return "login";*/
		//主体
		Subject subject = SecurityUtils.getSubject();
		//身份
		ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
		model.addAttribute("activeUser", activeUser);
		return "index";
	}

	/**
	 * 用户登陆
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/login", method = {RequestMethod.POST, RequestMethod.GET})
	public String login(HttpServletRequest request, HttpServletResponse response) throws Exception{


		// shiro在认证过程中出现错误后将异常类路径通过request返回

		String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
		if(exceptionClassName!=null){
			if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
				throw new CustomException("账号不存在");
			} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
				throw new CustomException("用户名或者密码错误");
			} else{
				throw new Exception();//最终在异常处理器生成未知错误
			}
		}
		/*ResponseDTO responseDTO = new ResponseDTO();
		responseDTO.setSuccess(true);*/
		return "login";


	//shiro之前写法
	/*	ResponseDTO responseDTO = new ResponseDTO();
		try {
			UserDO userDO = userService.findUserByPhone(user.getPhone());
			if (userDO == null) {
				throw new CustomException("用户: " + user.getPhone() + " 不存在");
			}
			//加密的密码
			final String password = new Sha256Hash(user.getPassword()).toHex();
			if (!userDO.getPassword().equals(password)) {
				throw new CustomException("用户名或者密码错误");
			}
			if(userDO.isDelete()){
				throw new CustomException("当前用户暂时不可用，请联系管理员");
			}
			request.getSession().setAttribute(SessionConstant.SESSION_USER_INFO, userDO);
			//TODO shiro 集成 权限处理
			responseDTO.setCode(HttpRequestConstant.REQUEST_SUCCESS_CODE);
			responseDTO.setMessage("登陆成功");
			responseDTO.setSuccess(true);
			logger.debug("用户 : " + userDO.getUsername() + " 登陆了");
		} catch (CustomException e) {
			responseDTO.setCode(HttpRequestConstant.CLIENT_ERROR_CODE);
			responseDTO.setMessage(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage("服务器错误");
		}
		return responseDTO;*/
	}

	/**
	 * 用户注册
	 *
	 * @param request
	 * @param response
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/register", method = {RequestMethod.POST})
	public
	@ResponseBody
	ResponseDTO register(HttpServletRequest request, HttpServletResponse response, UserDO user) {
		ResponseDTO responseDTO = new ResponseDTO();
		try {
			UserDO userDO = userService.findUserByPhone(user.getPhone());
			if (userDO != null) {
				responseDTO.setMessage("用户: " + user.getPhone() + " 已注册");
				return responseDTO;
			}
			//加密密码
			Md5Hash md5Hash = new Md5Hash(user.getPhone(), ShiroMd5HashConstant.SALT, ShiroMd5HashConstant.HASH_ITERATIONS);
			String password_md5 =  md5Hash.toString();
			user.setPassword(password_md5);
			userService.registerUser(user);
			responseDTO.setCode(HttpRequestConstant.REQUEST_SUCCESS_CODE);
			responseDTO.setSuccess(true);
			//responseDTO.setData(user);
			//request.getSession().setAttribute(SessionConstant.SESSION_USER_INFO, userDO);
			responseDTO.setMessage("注册成功");
		} catch (Exception e) {
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage("服务器异常");
		}
		return responseDTO;
	}

	/**
	 * 退出登陆
	 *
	 * @param request
	 * @param response
	 * @return
	 */
/*	@RequestMapping(value = "/logout")
	public String logout(HttpServletRequest request, HttpServletResponse response) {
		request.getSession().invalidate();
		return "login";
	}*/
	@RequestMapping(value = "/refuse")
	public String refuse(HttpServletRequest request, HttpServletResponse response) {
		//区分是ajax请求还是普通请求
		String hande = request.getHeader("x-requested-with");   //XMLHttpRequest为ajax请求，null为正常请求
		if (hande != null && hande.equalsIgnoreCase("XMLHttpRequest")){//ajax请求
			response.setCharacterEncoding("UTF-8");
			response.setContentType("text/html;charset=utf-8");
			ResponseDTO result = new ResponseDTO();
			result.setCode("999");
			result.setMessage("权限不足");
			PrintWriter out = null;
			try {
				out = response.getWriter();
			} catch (IOException e) {
				e.printStackTrace();

			}

			String json = JSONObject.fromObject(result).toString();
			out.write(json);
			out.flush();
			out.close();
			return null;
		}
		return "content/error-404";
	}

	/**
	 * 根据页面的hash值来获取指定资源
	 *
	 * @param page 页面传来的hash
	 * @return
	 * @throws InterruptedException
	 */
	@RequestMapping(value = "/urlRepeater")
	public String urlRepeater(HttpServletRequest request, HttpServletResponse response,String page) throws InterruptedException {
		String url = StringUtils.humpToPartition(page, "/");
		logger.debug("访问了路径：" + url);
		if (url != null) {
			return "content/" + url;
		}
		return "content/error-404";
	}

	/**
	 * 分页用户信息
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequiresPermissions("USER:VIEW")
	@RequestMapping("/getUserInfo")
	public
	@ResponseBody
	PageDTO<CustomUser> getUserInfo(HttpServletRequest request, HttpServletResponse response) {
		Integer page = Integer.valueOf(request.getParameter("page"));
		Integer pageSize = Integer.valueOf(request.getParameter("rows"));
		String sortedKey = request.getParameter("sidx");
		String sortedValue = request.getParameter("sord");
		String filters = request.getParameter("filters");
		PageDTO<CustomUser> result = null;
		try {
			result = userService.findUserByPage(page, pageSize, sortedKey, sortedValue, filters);
		} catch (CustomException e) {
			logger.error("获取用户失败");
			e.printStackTrace();
			result = new PageDTO<>();
		}
		return result;
	}

	@RequestMapping("/editUserInfo")
	public
	@ResponseBody
	ResponseDTO editUserInfo(HttpServletRequest request, HttpServletResponse response,CustomUser user) {
		ResponseDTO responseDTO = new ResponseDTO();
		String oper = request.getParameter("oper");
		try {
			UserDO userDO = userService.findUserByPhone(user.getPhone());
			if (userDO != null && !userDO.getId().equals(user.getId())) {
				responseDTO.setMessage("用户: " + user.getPhone() + " 已存在");
				return responseDTO;
			}
			if ("add".equals(oper)) {
				//加密密码
				Md5Hash md5Hash = new Md5Hash(user.getPhone(), ShiroMd5HashConstant.SALT, ShiroMd5HashConstant.HASH_ITERATIONS);
				String password_md5 =  md5Hash.toString();
				user.setPassword(password_md5);
			}
			userService.editUserInfo(user,oper);
			responseDTO.setSuccess(true);
			responseDTO.setCode(HttpRequestConstant.REQUEST_SUCCESS_CODE);
			responseDTO.setMessage("操作成功");
		} catch (CustomException e) {
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage(e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage("未知错误");
			e.printStackTrace();
		}
		return responseDTO;

	}
	@RequestMapping(value = "/initializeUserPassword", method = {RequestMethod.GET})
	public
	@ResponseBody
	ResponseDTO initializeUserPassword(HttpServletRequest request, HttpServletResponse response, UserDO user) {
		ResponseDTO responseDTO = new ResponseDTO();
		try {
			Md5Hash md5Hash = new Md5Hash(user.getPassword(), ShiroMd5HashConstant.SALT, ShiroMd5HashConstant.HASH_ITERATIONS);
			String password_md5 =  md5Hash.toString();
			user.setPassword(password_md5);
			userService.initializeUserPassword(user);
			responseDTO.setSuccess(true);
		} catch (CustomException e) {
			responseDTO.setCode(HttpRequestConstant.CLIENT_ERROR_CODE);
			responseDTO.setMessage(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage("服务器错误");
		}
		return responseDTO;
	}

	@RequestMapping("/getUserInfoAndRoleAndPrivilige")
	public @ResponseBody
    ResponseDTO getUserInfoAndRoleAndPrivilige() throws Exception {
		ResponseDTO responseDTO = new ResponseDTO();
		Subject subject = SecurityUtils.getSubject();
		ActiveUser activeUser = (ActiveUser) subject.getPrincipal();

		try {
			Map<String,Object> result = userService.findUSerRoleNameAndPrivilegeNames(activeUser.getRoleId());
			result.put("username", activeUser.getUsername());
			result.put("phone",activeUser.getPhone());
			responseDTO.setData(result);
			responseDTO.setCode(HttpRequestConstant.REQUEST_SUCCESS_CODE);
			responseDTO.setSuccess(true);
		} catch (CustomException e) {
			responseDTO.setCode(HttpRequestConstant.CLIENT_ERROR_CODE);
			responseDTO.setMessage(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			responseDTO.setCode(HttpRequestConstant.SERVER_ERROR_CODE);
			responseDTO.setMessage("服务器错误");
		}
		return responseDTO;
	}

	@RequestMapping("/editPassword")
	public @ResponseBody
    ResponseDTO editPassword(String password) throws Exception {
		ResponseDTO responseDTO = new ResponseDTO();
		Subject subject = SecurityUtils.getSubject();
		ActiveUser activeUser = (ActiveUser) subject.getPrincipal();

		UserDO user = new UserDO();
		user.setPhone(activeUser.getPhone());
		Md5Hash md5Hash = new Md5Hash(password, ShiroMd5HashConstant.SALT, ShiroMd5HashConstant.HASH_ITERATIONS);
		user.setPassword(md5Hash.toString());

		userService.initializeUserPassword(user);
		responseDTO.setCode(HttpRequestConstant.REQUEST_SUCCESS_CODE);
		responseDTO.setSuccess(true);
		responseDTO.setMessage("修改成功");
		return responseDTO;
	}

	/**
	 * 安顺自动登陆页面
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/autoLogin")
	public String autoLogin(HttpServletRequest request,String phone,String url,String custCode) {
		request.setAttribute("phone",phone);
		request.setAttribute("url",url);
		request.setAttribute("custCode",custCode);
		return "content/system/autoLogin";
	}
	/**
	 * 自动登陆方法
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/autoLoginAuth")
	public @ResponseBody
    ResponseDTO autoLoginAuth(String username, String password) {
		ResponseDTO responseDTO = new ResponseDTO();
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		try {
			//4、登录，即身份验证
			subject.login(token);
			responseDTO.setSuccess(true);
		} catch (AuthenticationException e) {
			//5、身份验证失败
			e.printStackTrace();
			responseDTO.setMessage("用户不存在");
		}
		return responseDTO;
	}

	/**
	 * 发送短信验证码
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/sendMSM", produces = "application/json; charset=utf-8")
	public @ResponseBody
    String sendMSM(HttpServletRequest request, String phone, HttpServletResponse response) {
		String code = "";
		//6位随机数验证码
		for(int i=1;i<=6;i++) {
			int d = (int) (Math.random() * 10);
			code += d;
		}
		SMSUtil.sendCode(phone,code);
		return code;
	}
}
